package com.uestc.ui;

import com.uestc.config.InitPath;
import com.uestc.utils.*;
import javafx.geometry.Insets;
import javafx.scene.layout.HBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.*;
import com.browniebytes.javafx.control.*;

import java.io.File;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class PackView {
    private static List<File> selectedFiles;
    private static String selectedOption;
    private static String targetPrePath;
    private static boolean isScheduled;
    private static boolean isOnce;
    private static boolean isRepeat;
    private static int hours;
    private static int minutes;
    private static int seconds;
    private static LocalDateTime scheduledTime;

    public static void showPackDialog() {
        Stage dialog = new Stage();
        dialog.setTitle("打包");
        VBox vbox = new VBox(10, new Label("Select files:"), new Button("Browse"), new TextArea(), // 文件列表显示
                new Label("Select pack method:"), new ComboBox<>(), new Label("Select destination folder:"), new Button("Browse"), new TextField(), // 目标文件夹路径显示
                new CheckBox("scheduled pack up"), createScheduledBackupBox(), // 使用自定义方法创建Scheduled
                new HBox(30));

        Button browseFilesButton = (Button) vbox.getChildren().get(1);

        TextArea filesTextArea = (TextArea) vbox.getChildren().get(2); // 选中文件列表显示
        filesTextArea.setWrapText(true); // 允许文本自动换行
        filesTextArea.setPrefRowCount(10); // 设置首选行数，可以根据需要调整
        filesTextArea.setPrefHeight(100); // 设置首选高度，可以根据需要调整
        filesTextArea.setEditable(false); // 设置为只读，用户不能编辑内容

        ComboBox<String> packMethodComboBox = (ComboBox<String>) vbox.getChildren().get(4);

        Button browseFolderButton = (Button) vbox.getChildren().get(6);

        TextField folderTextField = (TextField) vbox.getChildren().get(7); // 目标文件夹路径显示
        folderTextField.setEditable(false);

        CheckBox scheduledCheckBox = (CheckBox) vbox.getChildren().get(8);

        HBox scheduledBox = (HBox) vbox.getChildren().get(9);
        scheduledBox.setDisable(true);

        HBox lastBox = (HBox) vbox.getChildren().get(10);
        Button packButton = new Button("pack up");
        Button backButton = new Button("back");
        lastBox.getChildren().addAll(packButton, backButton);
        lastBox.setMargin(packButton, new Insets(0, 0, 30, 0));

        browseFilesButton.setOnAction(e -> {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setInitialDirectory(new File(InitPath.path));
            fileChooser.setTitle("Choose files");
            selectedFiles = fileChooser.showOpenMultipleDialog(dialog);
            // Handle selected files
            if (selectedFiles != null) {
                StringBuilder fileList = new StringBuilder();
                for (File file : selectedFiles) {
                    fileList.append(file.getName()).append("\n"); // 使用换行符
                }
                if (fileList.length() > 0) {
                    fileList.setLength(fileList.length() - 1);
                }
                filesTextArea.setText(fileList.toString());
            }
        });

        packMethodComboBox.getItems().addAll("only copy", "tar", "huff", "aes");
        packMethodComboBox.setOnAction(e -> {
            selectedOption = packMethodComboBox.getValue();
        });

        browseFolderButton.setOnAction(e -> {
            // 选择一个文件夹
            DirectoryChooser directoryChooser = new DirectoryChooser();
            directoryChooser.setInitialDirectory(new File(InitPath.path));
            directoryChooser.setTitle("Choose one director");
            File file = directoryChooser.showDialog(dialog);
            targetPrePath = file.getPath();
            folderTextField.setText(targetPrePath);

        });

        scheduledCheckBox.setOnAction(e -> {
            isScheduled = scheduledCheckBox.isSelected();
            scheduledBox.setDisable(!isScheduled);
        });

        packButton.setOnAction(e -> {
            if (isScheduled) {
                if (isOnce != isRepeat) {
                    handleScheduledPack(isOnce);
                } else {
                    AlertUtil.showAlert("请选择定时方式");
                }
            } else {
                handlePack();
            }
        });

        backButton.setOnAction(e -> {
            dialog.close();
            MainMenu.showLocalDialog();
        });

        Scene scene = new Scene(vbox, 600, 600);
        dialog.setTitle("File Packer");
        dialog.setScene(scene);
        dialog.show();
    }

    private static void handleScheduledPack(boolean isOnce) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        int interval = (3600 * hours) + (60 * minutes) + seconds; // 单位：s
        Runnable task = getRunnable(dateFormat);

        if (isOnce) {
            LocalDateTime now = LocalDateTime.now(); // 当前时间
            long duration = Duration.between(now, scheduledTime).toMillis();
            AlertUtil.showAlert("程序将在 " + scheduledTime + " 继续执行");
            // 如果目标时间在当前时间之后，暂停程序
            if (duration > 0) {
                scheduledTask(task, duration, TimeUnit.MILLISECONDS);
            } else {
                System.out.println("目标时间已过，程序继续执行");
            }
        } else {
            repeatTask(task, 0, interval, TimeUnit.SECONDS);
        }
    }

    private static Runnable getRunnable(SimpleDateFormat dateFormat) {
        Runnable task = null;
        if (selectedFiles == null || selectedOption == null || targetPrePath == null) {
            AlertUtil.showAlert("前置选项不能为空");
        } else if (selectedOption.equals("only copy")) {
            task = () -> CopyUtil.copyFile(selectedFiles, targetPrePath);

        } else if (selectedOption.equals("tar")) {
            task = new Runnable() {
                @Override
                public void run() {
                    String currentTime = dateFormat.format(new Date());
                    String targetPath = targetPrePath + "\\" + currentTime + ".tar";
                    PackUtil.packFile(selectedFiles, targetPath);
                }
            };

        } else if (selectedOption.equals("huff")) {
            task = () -> {
                String currentTime = dateFormat.format(new Date());
                String targetPath = targetPrePath + "\\" + currentTime + ".huff";
                HuffmanCoding.compress(selectedFiles, targetPath);
            };
        } else if (selectedOption.equals("aes")) {
            if (selectedFiles.size() > 1) {
                AlertUtil.showAlert("请只选择一个文件进行加密");
            }
            File file = selectedFiles.get(0);
            DialogUtil.showPasswordDialog("Please input Password", "Password");
            String password = DialogUtil.getPassword();
            if (password != null) {
                task = () -> {
                    String targetPath = targetPrePath + "\\" + file.getName() + ".aes";
                    OpenSSLUtil.encryptFile(password, file.getPath(), targetPath);
                };
            }
        }
        return task;
    }

    private static void handlePack() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String currentTime = dateFormat.format(new Date());
        String targetPath = targetPrePath;
        if (selectedFiles == null || selectedOption == null || targetPrePath == null) {
            AlertUtil.showAlert("前置选项不能为空");
            return;
        } else if (selectedOption.equals("only copy")) {
            CopyUtil.copyFile(selectedFiles, targetPath);
        } else if (selectedOption.equals("tar")) {
            targetPath = targetPrePath + "\\" + currentTime + ".tar";
            PackUtil.packFile(selectedFiles, targetPath);
        } else if (selectedOption.equals("huff")) {
            targetPath = targetPrePath + "\\" + currentTime + ".huff";
            HuffmanCoding.compress(selectedFiles, targetPath);
        } else if (selectedOption.equals("aes")) {
            if (selectedFiles.size() > 1) {
                AlertUtil.showAlert("请只选择一个文件进行加密");
            }
            File file = selectedFiles.get(0);
            DialogUtil.showPasswordDialog("Please input Password", "Password");
            String password = DialogUtil.getPassword();
            if (password != null) {
                targetPath = targetPrePath + "\\" + file.getName() + ".aes";
                OpenSSLUtil.encryptFile(password, file.getPath(), targetPath);
            } else {
                return;
            }
        }
        AlertUtil.showAlert("打包成功");
    }

    private static HBox createScheduledBackupBox() {
        HBox mainHbox = new HBox(50); // 创建HBox并设置间距

        VBox vBox1 = new VBox(15);
        VBox vBox2 = new VBox(10);


        // 创建两个RadioButton
        RadioButton option1 = new RadioButton("only once");
        RadioButton option2 = new RadioButton("repeat");

        // 创建一个ToggleGroup并添加RadioButton
        ToggleGroup toggleGroup = new ToggleGroup();
        option1.setToggleGroup(toggleGroup);
        option2.setToggleGroup(toggleGroup);


        DateTimePicker timePicker = new DateTimePicker(); // 用于单次备份时间
        timePicker.dateTimeProperty().addListener((observable, oldValue, newValue) -> {
            scheduledTime = timePicker.dateTimeProperty().get();
        });

        HBox hBox1 = new HBox(10);
        hBox1.setVisible(false);
        hBox1.getChildren().addAll(new Label("scheduled time:"), timePicker);

        HBox hBox2 = new HBox(10);
        hBox2.setVisible(false);

        TextField hourTextField = new TextField();
        hourTextField.setPrefWidth(50);
        hourTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.matches("\\d*")) {
                hourTextField.setText(oldValue);
            }
            hours = Integer.parseInt(hourTextField.getText());
        });

        TextField minuteTextField = new TextField();
        minuteTextField.setPrefWidth(50);
        minuteTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.matches("\\d*")) {
                minuteTextField.setText(oldValue);
            }
            minutes = Integer.parseInt(minuteTextField.getText());
        });

        TextField secondTextField = new TextField();
        secondTextField.setPrefWidth(50);
        secondTextField.textProperty().addListener((observable, oldValue, newValue) -> {
            if (!newValue.matches("\\d*")) {
                secondTextField.setText(oldValue);
            }
            seconds = Integer.parseInt(secondTextField.getText());
        });

        hBox2.getChildren().addAll(new Label("interval:"), hourTextField, new Label("hours"), minuteTextField, new Label("minutes"), secondTextField, new Label("seconds"));

        option1.setOnAction(e -> {
            hBox1.setVisible(true);
            hBox2.setVisible(false);
            isOnce = true;
            isRepeat = false;
        });
        option2.setOnAction(e -> {
            hBox1.setVisible(false);
            hBox2.setVisible(true);
            isOnce = false;
            isRepeat = true;
        });


        vBox1.getChildren().addAll(option1, option2);
        vBox2.getChildren().addAll(hBox1, hBox2);
        // 将复选框和单次备份时间选择器添加到HBox
        mainHbox.getChildren().addAll(vBox1, vBox2);
        return mainHbox;
    }

    public static void repeatTask(Runnable task, long initialDelay, long period, TimeUnit timeUnit) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        // 定时执行任务
        scheduler.scheduleAtFixedRate(task, initialDelay, period, timeUnit);
        StringBuilder sb = new StringBuilder();
        for (File file : selectedFiles) {
            sb.append(file.getName());
            sb.append(" ");
        }
        AlertUtil.showAlert("文件" + sb + "正在定时备份" + ",间隔为" + period + "秒");
    }

    public static void scheduledTask(Runnable task, long initialDelay, TimeUnit timeUnit) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        // 定时执行任务
        scheduler.schedule(task, initialDelay, timeUnit);
        StringBuilder sb = new StringBuilder();
        for (File file : selectedFiles) {
            sb.append(file.getName());
            sb.append(" ");
        }
    }
}